﻿using System;
using System.Runtime.InteropServices;

namespace LSA.Framework.Pinvoke
{
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct SvdResult
    {
        /// <summary>
        /// Dimensionality
        /// </summary>
        public int d;
        /// <summary>
        /// Transpose of left singular vectors. (d by m).
        /// </summary>
        public IntPtr Ut;
        /// <summary>
        /// Array of singular values. (length d)
        /// </summary>
        public double* S;
        /// <summary>
        /// Transpose of right singular vectors. (d by n).
        /// </summary>
        public IntPtr Vt;

        //private DenseMatrix* singularValues;

        public DenseMatrix GetUt()
        {
            return (DenseMatrix) Marshal.PtrToStructure(Ut, typeof (DenseMatrix));
        }

        public DenseMatrix GetVt()
        {
            return (DenseMatrix)Marshal.PtrToStructure(Vt, typeof(DenseMatrix));
        }

        public DenseMatrix* GetSingularValues()
        {
            //if (singularValues != null) return singularValues;
            DenseMatrix* singularValues;
            singularValues = CppInvoker.BuildNewDenseMatrix(d, d);
            for (int i = 0; i < d; i++)
            {
                singularValues->value[i][i] = S[i];
            }
            return singularValues;
        }
    };
}
